/*
 *================================================================================
 *	Plik: f_rol.c
 *	Created on: Jun 4, 2011
 *--------------------------------------------------------------------------------
 *	Autorzy: Piotr Zdunek, Mateusz Słowikowski, Krzysztof Wiąckowski
 *	Projekt: Model mikrokontrolera AVR
 *	Kompilator: avr-gcc-4.3.5
 *	Doc: doxygen 1.4.3
 *--------------------------------------------------------------------------------
 *	Zawiera: Implementację funkcji ROL
 *--------------------------------------------------------------------------------
 *	Komentarze:
 *================================================================================
 */

/*! \file f_rol.c
 * \brief Plik opisujący funkcję ROL
 */

#include "types.h"
#include "mem_abs.h"

void F_ROL() {
	/*!  void F_ROL(void){}
	 *  \n \n
	 *  ROL - funkcja przesuwająca w lewo bity w rejestrze. Po przesunięciu w lewo
	 *  najstarszy bit przed przesunięciem zostanie zapisany w miejsce flagi C, a flaga C
	 *  zostaje zapisana w miejsce najmłodszego bitu.
	 *
	 *  \ref pagerol \n
	 */
	 
#ifndef  DEBUG_MODE
	printf("Function ROL.");
#endif

	//Resolve variable value form opcode
	uint8_t Rd = (((getMEMC(getPC()) & 0x0FFF) & 0b000111110000) >> 4);
	uint8_t Rd_val = getRegister(Rd) % MAX_DATA_VAL;

	if ( GetRegisterBitStatus(Rd_val,MSB) == 0) {
		ClearFlagRegisterBit(FLAG_C);
	} else if ( GetRegisterBitStatus(Rd_val,MSB) == 1) {
		SetFlagRegisterBit(FLAG_C);
	}

	Rd_val = Rd_val << 1;

	//ustawienie ostatenigo bitu rejestru - przyjmuje wartość flagi C
	if (GetFlagRegisterStatus(FLAG_C) == 1) {
		//Setting lsb
		SetRegisterBit(Rd_val, LSB);
	} else {
		ClearRegisterBit(Rd_val, LSB);
	}
	//Ustawienie flagi H

	if (GetRegisterBitStatus(Rd_val, BIT_3)) {
		SetFlagRegisterBit(FLAG_H);
	} else {
		ClearFlagRegisterBit(FLAG_H);
	}

	if (GetRegisterBitStatus(Rd_val, MSB) == 1) {
		SetFlagRegisterBit(FLAG_N);
	} else {
		ClearFlagRegisterBit(FLAG_N);
	}
	//ustawienie flagi V

	if ((GetFlagRegisterStatus(FLAG_N) ^ GetFlagRegisterStatus(FLAG_C)) == 1) {
		SetFlagRegisterBit(FLAG_V);
	} else {
		ClearRegisterBit(FLAG_V);
	}

	//ustawienie flagi S
	if ((GetFlagRegisterStatus(FLAG_N) ^ GetFlagRegisterStatus(FLAG_V)) == 1) {
		SetFlagRegisterBit(FLAG_S);
	} else {
		ClearRegisterBit(FLAG_S);
	}

	if (Rd_val == 0) {
		SetFlagRegisterBit(FLAG_Z); //ustwienie flagi Z
	} else {
		ClearFlagRegisterBit(FLAG_Z);
	}

	setRegister(Rd, Rd_val);
	incPC();

}

/*! \page pagerol Opis działania funkcji ROL
 *
 *  ROL - funkcja przesuwająca w lewo bity w rejestrze. Po przesunięciu w lewo
 *  najstarszy bit przed przesunięciem zostanie zapisany w miejsce flagi C, a flaga C
 *  zostaje zapisana w miejsce najmłodszego bitu.
 *
 *	\dontinclude f_rol.c
 *
 *	\section sec_rolone Operacje rejestrowe oraz arytmetyczno-logiczne
 *
 *	1. Pobranie adresu i wartości rejestru:
 *	\skipline uint8_t
 *	\until MAX_DATA_VAL
 *	2. Ustalenie wartości flagi C:
 *	\skipline if
 *	\until SetFlagRegisterBit(FLAG_C)
 *	\until }
 *	3. Przesunięcie zawartości rejestru:
 *	\skipline Rd_val
 *	4. Zapisanie ostatniego bitu rejestru:
 *	\skipline if
 *	\until ClearRegisterBit(Rd_val, LSB)
 *	\until }
 *
 *	\section sec_roltwo Operacje na flagach
 *
 *	5. Wyzerowanie flagi H
 *	\skipline if
 *	\until ClearFlagRegisterBit
 *	\until }
 *	6. Ustawienie flagi N
 *	\line if
 *	\until ClearFlagRegisterBit
 *	\until }
 *	7. Ustawienie flagi V
 *	\line if
 *	\until ClearRegisterBit(FLAG_V)
 *	\until }
 *	8. Ustawienie flagi S
 *	\line if
 *	\until ClearRegisterBit(FLAG_S)
 *	\until }
 *	9. Ustawienie flagi Z
 *	\line if
 *	\until ClearFlagRegisterBit(FLAG_Z)
 *	\until }
 *
 *	\section sec_roltrzy Zapis wyniku
 *
 *	10. Zapisanie nowej zawartości Rd
 *	\skipline setRegister
 *	11. Zwiększenie PC
 *	\skipline incPC
 *
 *	\section sec_rolfour Kod źródłowy funkcji
 *
 *	\include f_rol.c
 *
 */
